from rest_framework import status
import logging

from rest_framework.decorators import action
from rest_framework.mixins import ListModelMixin, CreateModelMixin
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet
from shopping.models import Classification, Commodity, CommodityImg, ShoppingCart, Order
from shopping.serializers import ClassificationsSerializer, ParentClassificationsSerializer, CommoditySerializer, \
    ShoppingCartSerializer, OrderSerializer
from fdfs_client.client import Fdfs_client, get_tracker_conf

# # 创建日志对象
logger = logging.getLogger('__name__')
# 创建fastdfs客户端对象
tracker_path = get_tracker_conf("fastdfs/client.conf")
# 通过配置文件地址 创建fastdfs的客户端
client = Fdfs_client(tracker_path)


# 分类的视图
# 只需要 查看的功能
class ClassificationViewSet(GenericViewSet, ListModelMixin):
    queryset = Classification.objects.filter(is_delete=False)
    serializer_class = ClassificationsSerializer
    # 登录权限
    permission_classes = [IsAuthenticated]

    # 查询集
    # 查看所有的分类的时候  只展示一级分类   list
    def get_queryset(self):
        if self.action == 'list':
            # 没有被逻辑删除的  并且  没有父级 parent
            return self.queryset.filter(parent__isnull=True)
        else:
            return self.queryset

    @action(methods=['get'], detail=True)
    def commodity(self, request, pk):
        # 根据传入的id获取指定的分类
        try:
            # 获取模型对象 实例对象
            # classification = Classification.objects.get(id=id)
            classification_res = self.get_queryset().get(id=pk)
        except Classification.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)
        # 该分类是几级分类
        # 默认一级分类
        classification_attr = "classification1"
        # 名字
        classification_name = classification_res.name
        # 如果存在父级id
        if classification_res.parent:
            classification_attr = "classification2"
            classification_name = f"{classification_res.parent.name}-----{classification_res.name}"
        # 得到分类数据
        data = getattr(classification_res, classification_attr)
        clear_data = data.filter(status=1, is_delete=False)
        return Response({
            "classification": classification_name,
            "commodity": CommoditySerializer(clear_data, many=True).data,
        })

    def get_serializer_class(self):
        if self.action == 'list':
            return ParentClassificationsSerializer
        else:
            return self.serializer_class


# 商品的视图
class CommodityViewSet(ModelViewSet):
    queryset = Commodity.objects.filter(is_delete=False)
    serializer_class = CommoditySerializer
    permission_classes = [IsAuthenticated]

    # 查询接口必须是发布的
    def get_queryset(self):
        if self.action in ['list', 'retrieve']:
            return self.queryset.filter(status=1)
        else:
            return self.queryset

    # 添加商品 添加图片
    # 重写create
    def create(self, request, *args, **kwargs):
        # 客户端数据 反序列化
        serializer = self.get_serializer(data=request.data)
        # 检验
        serializer.is_valid(raise_exception=True)
        # 保存
        serializer.save()

        # 商品图片的获取
        files = request.FILES.getlist('file')
        for file in files:
            if file:
                # 判断是否是图片
                if file.content_type not in ['image/png', 'image/jpeg']:
                    return Response(status=status.HTTP_400_BAD_REQUEST)
                try:
                    # 如果没有文件后缀 1.png
                    image_ext_name = file.name.split('.')[-1]  # ["1" , "png"]
                except Exception as e:
                    logger.info(f"图片的扩展名异常{e}")
                    image_ext_name = "png"
                # 进行持久化存储  storage（存储服务端）
                try:
                    # upload_by_filename  ==> upload_by_buffer
                    # 数据 和文件的后缀  ===》 storage  ===》xxxxxx.png
                    uploade_res = client.upload_by_buffer(file.read(), file_ext_name=image_ext_name)
                except Exception as e:
                    logger.error(f"图片上传出现异常{e}")
                    return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)
                else:
                    # 再进行数据库的持久化存储  图片地址
                    if uploade_res.get("Status") != "Upload successed.":
                        logger.warning("图片上传失败")
                        return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)
                    else:
                        # 字节文件  ===》 字符文件
                        image_url = uploade_res.get("Remote file_id").decode()

                        # 存入到图片数据库中
                        CommodityImg.objects.create(src=image_url, commodity_id=serializer.data.get('id'))

        return Response(serializer.data, status=status.HTTP_201_CREATED)

    # 注册商城优选数据展示
    @action(methods=['get'], detail=False)
    def optimization(self, request):
        # 获取商城优选数据
        queryres = self.get_queryset().order_by('-sales').order_by('-comments').order_by('-created_time')
        # 序列化
        if len(queryres) >= 5:
            queryres = queryres[:5]
        serializer = self.get_serializer(queryres, many=True)
        return Response(serializer.data)


# 购物车 真删除
class ShoppingCartViewSet(ModelViewSet):
    queryset = ShoppingCart.objects.all()
    serializer_class = ShoppingCartSerializer
    permission_classes = [IsAuthenticated]

    # 只有该用户才能操作自己的购物车
    def get_queryset(self):
        return self.request.user.shoppingcart_set.all()

    def create(self, request, *args, **kwargs):
        request.POST._mutable = True
        request.data['user'] = request.user.id
        return super().create(request, *args, **kwargs)

# 订单   创建订单    用户只能读取订单
class OrderViewSet(ReadOnlyModelViewSet,CreateModelMixin):
    queryset = Order.objects.all()
    serializer_class = OrderSerializer
    permission_classes = [IsAuthenticated]

    # 只有该用户才能查看该用户的订单
    def get_queryset(self):
        # 获取对应用户的所有订单
        return self.request.user.order_set.all()